<template>
  <div class="tutorial-page">
    <div class="tutorial-header">
      <h1>Vue 生命周期</h1>
      <p>掌握Vue实例的生命周期钩子函数及其应用场景</p>
    </div>

    <div class="tutorial-content">
      <div class="section">
        <h2>Vue 3 生命周期概览</h2>
        <p>Vue 实例有一个完整的生命周期，从创建到销毁会经历一系列的过程。在这些过程中，Vue 提供了不同的钩子函数，允许我们在特定阶段运行自己的代码。</p>
        
        <h3>生命周期图示</h3>
        <div class="lifecycle-diagram">
          <div class="lifecycle-stage setup">
            <h4>setup()</h4>
            <p>Composition API 特有，在组件创建之前执行</p>
          </div>
          
          <div class="lifecycle-stage before-create">
            <h4>beforeCreate</h4>
            <p>实例初始化之后，数据观测和事件配置之前</p>
          </div>
          
          <div class="lifecycle-stage created">
            <h4>created</h4>
            <p>实例创建完成，已完成数据观测、属性和方法的运算</p>
          </div>
          
          <div class="lifecycle-stage before-mount">
            <h4>beforeMount</h4>
            <p>挂载开始之前被调用</p>
          </div>
          
          <div class="lifecycle-stage mounted">
            <h4>mounted</h4>
            <p>实例挂载到DOM上</p>
          </div>
          
          <div class="lifecycle-stage before-update">
            <h4>beforeUpdate</h4>
            <p>数据更新时调用，发生在虚拟DOM重新渲染和打补丁之前</p>
          </div>
          
          <div class="lifecycle-stage updated">
            <h4>updated</h4>
            <p>数据更改导致的虚拟DOM重新渲染和打补丁之后</p>
          </div>
          
          <div class="lifecycle-stage before-unmount">
            <h4>beforeUnmount</h4>
            <p>卸载组件实例之前调用</p>
          </div>
          
          <div class="lifecycle-stage unmounted">
            <h4>unmounted</h4>
            <p>卸载组件实例后调用</p>
          </div>
        </div>
      </div>

      <div class="section">
        <h2>Options API 生命周期钩子</h2>
        <pre><code class="language-javascript">export default {
  beforeCreate() {
    console.log('beforeCreate: 实例初始化之后')
  },
  created() {
    console.log('created: 实例创建完成')
    // 适合进行数据请求
  },
  beforeMount() {
    console.log('beforeMount: 挂载开始之前')
  },
  mounted() {
    console.log('mounted: 实例挂载到DOM')
    // 适合操作DOM元素
  },
  beforeUpdate() {
    console.log('beforeUpdate: 数据更新时调用')
  },
  updated() {
    console.log('updated: 虚拟DOM重新渲染后')
  },
  beforeUnmount() {
    console.log('beforeUnmount: 卸载组件实例之前')
  },
  unmounted() {
    console.log('unmounted: 卸载组件实例后')
    // 适合清理工作，如清除定时器、取消订阅等
  }
}</code></pre>
      </div>

      <div class="section">
        <h2>Composition API 生命周期钩子</h2>
        <p>在 Composition API 中，生命周期钩子需要从 vue 中显式导入：</p>
        <pre><code class="language-javascript">import { onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue'

export default {
  setup() {
    // setup 本身是 Composition API 特有的
    console.log('setup: 组件创建之前执行')
    
    onBeforeMount(() => {
      console.log('onBeforeMount: 挂载开始之前')
    })
    
    onMounted(() => {
      console.log('onMounted: 实例挂载到DOM')
      // 适合操作DOM元素
    })
    
    onBeforeUpdate(() => {
      console.log('onBeforeUpdate: 数据更新时调用')
    })
    
    onUpdated(() => {
      console.log('onUpdated: 虚拟DOM重新渲染后')
    })
    
    onBeforeUnmount(() => {
      console.log('onBeforeUnmount: 卸载组件实例之前')
    })
    
    onUnmounted(() => {
      console.log('onUnmounted: 卸载组件实例后')
      // 适合清理工作
    })
    
    return {
      // 返回给模板使用的数据和方法
    }
  }
}</code></pre>
      </div>

      <div class="section">
        <h2>实际应用场景</h2>
        
        <h3>created / setup 阶段</h3>
        <ul>
          <li>数据初始化</li>
          <li>异步数据请求</li>
          <li>事件监听器设置</li>
        </ul>
        
        <h3>mounted 阶段</h3>
        <ul>
          <li>DOM 操作</li>
          <li>第三方库初始化（如 echarts）</li>
          <li>定时器设置</li>
        </ul>
        
        <h3>unmounted 阶段</h3>
        <ul>
          <li>清理定时器</li>
          <li>取消网络请求</li>
          <li>移除事件监听器</li>
        </ul>
      </div>

      <div class="section">
        <h2>注意事项</h2>
        <ul>
          <li>不要在 <code>beforeCreate</code> 中访问 <code>data</code>、<code>methods</code> 等</li>
          <li><code>mounted</code> 不保证所有子组件都被挂载，如需等待，可以使用 <code>this.$nextTick()</code></li>
          <li><code>updated</code> 不要更改状态，否则可能造成无限循环</li>
          <li>在 <code>unmounted</code> 中进行清理工作，避免内存泄漏</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script setup>
// 页面逻辑可以在这里添加
</script>

<style scoped>
@import '@/assets/tutorial-styles.css';

.lifecycle-diagram {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  justify-content: center;
  margin: 30px 0;
}

.lifecycle-stage {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 20px;
  min-width: 200px;
  text-align: center;
  border: 2px solid #e9ecef;
  transition: all 0.3s ease;
}

.lifecycle-stage:hover {
  transform: translateY(-5px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.lifecycle-stage h4 {
  color: #42b883;
  margin-bottom: 10px;
  font-size: 1.2rem;
}

.lifecycle-stage p {
  font-size: 0.9rem;
  margin: 0;
}

.setup { border-color: #6f42c1; }
.setup h4 { color: #6f42c1; }

.before-create { border-color: #fd7e14; }
.before-create h4 { color: #fd7e14; }

.created { border-color: #20c997; }
.created h4 { color: #20c997; }

.before-mount { border-color: #0dcaf0; }
.before-mount h4 { color: #0dcaf0; }

.mounted { border-color: #0d6efd; }
.mounted h4 { color: #0d6efd; }

.before-update { border-color: #ffc107; }
.before-update h4 { color: #ffc107; }

.updated { border-color: #198754; }
.updated h4 { color: #198754; }

.before-unmount { border-color: #dc3545; }
.before-unmount h4 { color: #dc3545; }

.unmounted { border-color: #6c757d; }
.unmounted h4 { color: #6c757d; }

@media (max-width: 768px) {
  .lifecycle-diagram {
    flex-direction: column;
    align-items: center;
  }
  
  .lifecycle-stage {
    width: 100%;
    max-width: 300px;
  }
}
</style>